
package DBLayer;
import java.sql.*;
import ModelLayer.Machine;
import java.util.ArrayList;

/**
 * @version 12/22/2011
 * @author Gruppe 4
 */

public class DBMachine implements IFDBMachine {
    private Connection con;
    private PreparedStatement pStmtSelect;
    
    /**
     * Constructor for class DBMachine
     */
    public DBMachine(){
        con = DBConnection.getInstance().getDBcon();
    }
    
    /**
     * Method to find all machines from the database
     * @param ()
     * @return Returns an ArrayList<Machine>
     */
    @Override
    public ArrayList<Machine> getAllMachines(){
        return findMachinesWithPreQuery();
    }
    
    /**
     * Method to find a Machine object in the database
     * @param machineId int machineId the machineId of the machine
     * @return returns an Object of type Machine
     */
    @Override
    public Machine findMachine(int machineId, boolean retrieveAssociation)
    {   
        String wClause = " where machineId = ";
        Machine machineObj = new Machine();
        int value = machineId; 
        machineObj = findWithPreQuery(value, wClause, retrieveAssociation);
        
        return machineObj;
    }

    /**
     * Method to find a Machine object in the database
     * @param name String name the name of the machine
     * @return returns an Object of type Machine
     */
    @Override
    public Machine searchMachineName(String name, boolean retrieveAssociation)
    {   
        String wClause = "  where name = ";
        Machine machineObj = new Machine();
        String value = name;
        machineObj = findWithPreQuery(value, wClause, retrieveAssociation);
        
        return machineObj;
    }
    
    /**
     * Method to insert a Machine object into the database
     * @param machineObj an Object of the type Machine
     * @return returns an int 1 if the method succedes and -1 if the method fails
     */
    @Override
    public int insertMachine(Machine machineObj)
    {
        int rc = -1;
        
        //call to get the next Machine id
        int nextMachineId = getMaxId();
        nextMachineId = nextMachineId + 1;
        System.out.println("next machine id = " +  nextMachineId);
        
        PreparedStatement pstmt = null;
        String insert = "insert into Machine(machineId, type, name, fuelType, model, hourPrice, comment)"+
                     "values (?,?,?,?,?,?,?)";
        System.out.println(insert);
        try
        {
            pstmt = con.prepareStatement(insert);
            pstmt.setInt(1,nextMachineId);
            pstmt.setString(2, machineObj.getType());
            pstmt.setString(3,machineObj.getName());
            pstmt.setString(4, machineObj.getFuelType());
            pstmt.setString(5, machineObj.getModel());
            pstmt.setDouble(6, machineObj.getHourPrice());
            pstmt.setString(7, machineObj.getComment());
            
            rc = pstmt.executeUpdate();
        }//end try
        catch(SQLException sqlE)
        {
            System.out.println("SQL Error");
            System.out.println(sqlE.getMessage());
        }
        catch(Exception e)
        {
            e.getMessage();
        }
        
        return rc;
    }
    
    /**
     * Method to update a Machine in the database;
     * @param machine an Object of the type Machine
     * @return returns an int 1 if the method succedes and -1 if the method fails
     */
    @Override
    public int updateMachine(Machine machine)
    {
        Machine machineObj = machine;
        int rc=-1;
        
        PreparedStatement pstmt = null;
        
        String query="UPDATE Machine SET "+
                "type = ?, "+ 
                "name = ?, "+
                "fuelType = ?, "+
                "model = ?, "+
                "hourPrice = ?, "+
                "comment = ? "+
               
                " WHERE machineId = ?";
        
        System.out.println("Update query:" + query);
        	
        try
                { // update machine
                    pstmt = con.prepareStatement(query);
                    
                    pstmt.setString(1, machineObj.getType());
                    pstmt.setString(2, machineObj.getName());
                    pstmt.setString(3, machineObj.getFuelType());
                    pstmt.setString(4, machineObj.getModel());
                    pstmt.setDouble(5, machineObj.getHourPrice());
                    pstmt.setString(6, machineObj.getComment());
                    pstmt.setInt(7, machineObj.getMachineId());
                    
	 		
                        rc = pstmt.executeUpdate();
	 	 	pstmt.close();
		}//slut try
	 	catch(Exception ex){
	 	 	System.out.println("Update exception in machine db: "+ex);
	  	}
		return(rc);
    }
    
    /**
     * Method to delete a Machine from the database
     * @param machineId int machineId the id of the machine
     * @return returns an int 1 if the method succedes and -1 if the method fails
     */
    @Override
    public int deleteMachine(int machineId)
    {
        int rc = -1;
        PreparedStatement pstmt = null;
        String delete = "delete from Machine where machineId = ?";
        System.out.println(delete);
        try
        {
            pstmt = con.prepareStatement(delete);
            pstmt.setInt(1,machineId);
            rc = pstmt.executeUpdate(); 
        }
        catch(SQLException sqlE)
        {
            System.out.println("SQL Error");
            System.out.println(sqlE.getMessage());
        }
        catch(Exception e)
        {
            e.getMessage();
        }
        
        return rc;
    }
    
    /**
     * Method to build an object of type Machine
     * @param results 
     * @return Returns a machine object
     */
    private Machine buildMachine(ResultSet results, boolean retrieveAssociation)
    {
       Machine machineObj = new Machine();
       
         try{
               machineObj.setMachineId(results.getInt("machineId"));
               machineObj.setType(results.getString("type"));
               machineObj.setName(results.getString("name"));
               machineObj.setFuelType(results.getString("fuelType"));
               machineObj.setModel(results.getString("model"));
               machineObj.setHourPrice(results.getDouble("hourPrice"));
               machineObj.setComment(results.getString("comment"));
         }
         catch(Exception e)
         {
             System.out.println("building machine object");
         }
        
        return machineObj;
    }
    
    /**
     * Method that finds a Machine in the database 
     * @param machineId
     * @param wClause
     * @param retrieveAssociation 
     * @return Machine Object
     */
    private Machine findWithPreQuery(Object value, String wClause, boolean retrieveAssociation)
        {   
            System.out.println("Find with preCompiled");
            int machineId = 0;
            String name = "";
            if(pStmtSelect == null)
            {
               pStmtSelect =  getPreparedStmt(wClause);          
            }
            Machine mObj = null;
            ResultSet results;
            
            try
        {
            if(value instanceof Integer)
            {
                machineId = (Integer) value;
                pStmtSelect.setInt(1,machineId);
            }
            if(value instanceof String)
            {
                name = (String) value;
                pStmtSelect.setString(1,name);
            }
           
            results = pStmtSelect.executeQuery();
            if(results.next())
            {
                mObj = buildMachine(results, retrieveAssociation);
            }
        } 
        catch(Exception e)
        {
            e.getMessage();
        }
        
        return mObj;
    }
    
    /**
     * Method to create a prepared statement 
     * @param wClause String wClause
     * @return returns a PreparedStatment
     */
    private PreparedStatement getPreparedStmt(String wClause)
        {
           try{ 
            String query = "Select * FROM Machine " +
                           wClause + " ?";
            System.out.println("Preparestatement " + query);
            pStmtSelect = con.prepareStatement(query);
            
           }
           catch(Exception e)
           {
                e.getMessage();
            }
           return pStmtSelect;
        }
    
    /**
     * Method to create a prepared statement 
     * @param ()
     * @return returns a PreparedStatment
     */
    private PreparedStatement getAllPreparedStmt()
        {
           try{ 
            String query = "Select * FROM Machine";
            System.out.println("Preparestatement " + query);
            pStmtSelect = con.prepareStatement(query);
            
           }
           catch(Exception e)
           {
                e.getMessage();
            }
           return pStmtSelect;
        }
    
    /**
     * Method to get the highest machineId that excist in the database
     * @return returns the highest machineId
     */
    public int getMaxId()
    {
        int maxMachineId = GetMax.getMaxId("Select max(machineId) from Machine");
        return maxMachineId;
    }
    
     /**
     * Method that finds all Machines in the database 
     * @param ()
     * @return ArrayList<Machine> : list
     */
    private ArrayList<Machine> findMachinesWithPreQuery()
    {
        System.out.println("Find with preCompiled");
            
        if(pStmtSelect == null)
        {
            pStmtSelect =  getAllPreparedStmt();          
        }
        ArrayList<Machine> list = new ArrayList<Machine>();
        ResultSet results;

            try{
            results = pStmtSelect.executeQuery();
            while( results.next() )
            {
                Machine machineObj = new Machine();
		machineObj = buildMachine(results, false);	
                list.add(machineObj);
            }//end while  
        } 
        catch(Exception e)
        {
            e.getMessage();
        }
        
        return list;
    }
}